/**
 * 
 */
package net.xfok.ui.animation;

import android.view.ViewGroup;
import android.view.animation.AccelerateInterpolator;
import android.view.animation.Animation;
import android.view.animation.DecelerateInterpolator;

/**
 * @author howard
 *
 */
public abstract class Rotate3D{
	private int duration=500;
	private int swapDuration=500;
	private int from=180;
	private int to=360;
	private float depth=310.0f;
	private float swapDepth=310.0f;
	private ViewGroup mContainer;
	
	public Rotate3D(ViewGroup mContainer){
		this.setmContainer(mContainer);
	}
	
	public ViewGroup getmContainer() {
		return mContainer;
	}

	public void setmContainer(ViewGroup mContainer) {
		this.mContainer = mContainer;
	}

	public int getDuration() {
		return duration;
	}

	public void setDuration(int duration) {
		this.duration = duration;
	}

	public int getFrom() {
		return from;
	}

	public void setFrom(int from) {
		this.from = from;
	}

	public int getTo() {
		return to;
	}

	public void setTo(int to) {
		this.to = to;
	}

	public int getSwapDuration() {
		return swapDuration;
	}

	public void setSwapDuration(int swapDuration) {
		this.swapDuration = swapDuration;
	}

	public float getDepth() {
		return depth;
	}

	public void setDepth(float depth) {
		this.depth = depth;
	}

	public float getSwapDepth() {
		return swapDepth;
	}

	public void setSwapDepth(float swapDepth) {
		this.swapDepth = swapDepth;
	}

	public void applyRotation(float start, float end) {
        // Find the center of the container
        final float centerX = mContainer.getWidth() / 2.0f;
        final float centerY = mContainer.getHeight() / 2.0f;

        // Create a new 3D rotation with the supplied parameter
        // The animation listener is used to trigger the next animation
        final Rotate3DAnimation rotation =
                new Rotate3DAnimation(start, end, centerX, centerY, depth, true);
        rotation.setDuration(duration);
        rotation.setFillAfter(true);
        rotation.setInterpolator(new AccelerateInterpolator());
        rotation.setAnimationListener(new DisplayNextView());
        mContainer.startAnimation(rotation);
    }
	
	private final class DisplayNextView implements Animation.AnimationListener {

        public void onAnimationStart(Animation animation) {
        }

        public void onAnimationEnd(Animation animation) {
            mContainer.post(new SwapViews());
        }

        public void onAnimationRepeat(Animation animation) {
        }
    }

    /**
     * This class is responsible for swapping the views and start the second
     * half of the animation.
     */
    private final class SwapViews implements Runnable {

        public void run() {
            final float centerX = mContainer.getWidth() / 2.0f;
            final float centerY = mContainer.getHeight() / 2.0f;
            Rotate3DAnimation rotation=new Rotate3DAnimation(from, to, centerX, centerY, swapDepth, false);
            process();
            rotation.setDuration(swapDuration);
            rotation.setFillAfter(true);
            rotation.setInterpolator(new DecelerateInterpolator());
            mContainer.startAnimation(rotation);
        }
    }
    
    protected abstract void process();

}
